Head First Python 学习笔记-Chapter5:数据处理

本章的目的是学习简单的数据处理,首先给出了一些文本数据,需要将这些文本数据读取,并转换为列表,然后对列表中的数据进行统一格式化,最后进行排序。

本章所需的数据获取地址:获取数据

数据处理

未优化的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 对时间字符串进行格式化,统一形式为mins.secs
def sanitize(time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return(time_string)
(mins, secs) = time_string.split(splitter)
return(mins + '.' + secs)

# 读取文件,并将记录时间转换成列表
with open('james.txt') as jaf:
data = jaf.readline()
james = data.strip().split(',')

with open('julie.txt') as juf:
data = juf.readline()
julie = data.strip().split(',')

with open('mikey.txt') as mif:
data = mif.readline()
mikey = data.strip().split(',')

with open('sarah.txt') as saf:
data = saf.readline()
sarah = data.strip().split(',')

clean_james = []
clean_julie = []
clean_mikey = []
clean_sarah = []

---------臃肿的部分------------
for each_t in james:
clean_james.append(sanitize(each_t))

for each_t in julie:
clean_julie.append(sanitize(each_t))

for each_t in mikey:
clean_mikey.append(sanitize(each_t))

for each_t in sarah:
clean_sarah.append(sanitize(each_t))

print(sorted(clean_james))
print(sorted(clean_julie))
print(sorted(clean_mikey))
print(sorted(clean_sarah))
---------臃肿的部分------------

优化的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def sanitize(time_str):
if '-' in time_str:
spliter = '-'
elif ':' in time_str:
spliter = ':'
else:
return time_str
(mins, secs) = time_str.split(spliter)
return(mins + '.' + secs)

# 将读取文件的代码抽取成函数
def get_coach_data(filename):
try:
with open(filename) as file:
data = file.readline();
return data.strip().split(',')
except IOError as err:
print('File error:' + str(err))
return None

# 去除列表中的重复数据
def clean_data(data):
clean_data = []
for item in data:
if item not in clean_data:
clean_data.append(item)
return clean_data

james = get_coach_data('james.txt')
julie = get_coach_data('julie.txt')
mikey = get_coach_data('mikey.txt')
sarah = get_coach_data('sarah.txt')

james_format = [sanitize(data) for data in james]
julie_format = [sanitize(data) for data in julie]
mikey_format = [sanitize(data) for data in mikey]
sarah_format = [sanitize(data) for data in sarah]

clean_james = clean_data(james_format)
clean_julie = clean_data(julie_format)
clean_mikey = clean_data(mikey_format)
clean_sarah = clean_data(sarah_format)

print(sorted(clean_james)[0:3])
print(sorted(clean_julie)[0:3])
print(sorted(clean_mikey)[0:3])
print(sorted(clean_sarah)[0:3])

两种排序方法

原地排序(In-place sorting):data.sort()

该方法会对排列数据(data)按指定的顺序进行排序,然后用排好顺序的数据替换掉原有的数据,因此原有的数据顺序会丢失。

复制排序(Copied sorting):sorted(data)

对数据按指定的顺序进行排序,然后返回原数据的一个有序副本。原数据依然保留,只是对副本进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> data = [6,3,1,2,5,4]
>>> data
[6, 3, 1, 2, 5, 4]


>>> data.sort() # 对数据进行原地排序
>>> data
[1, 2, 3, 4, 5, 6] # 原数据的顺已经改变
>>>
>>> data = [6,3,1,2,5,4]
>>> data_sort = sorted(data) # 对数据进行复制排序,返回一个有序副本
>>> data
[6, 3, 1, 2, 5, 4] # 原数据顺序仍然存在


>>> data_sort
[1, 2, 3, 4, 5, 6]

列表推导式(list comprehension)

使用方法

[表达式 for 变量 in 列表] 或者 [表达式 for 变量 in 列表 if 条件]

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 将分钟数转化成秒数
>>> mins = [1,2,3]
>>> secs = [m * 60 for m in mins]
>>> secs
[60, 120, 180]

# 求列表中数字的平方
>>> data = [1,2,3,4]
>>> data_square = [num * num for num in data]
>>> data_square
[1, 4, 9, 16]

# 还可以跟其他条件,对列表中的数据进行筛选处理
>>> result = [num * 2 for num in data if num > 2]
>>> result
[6, 8]

# 也可以增加更多的for语句的部分:
>>> result = [[x,y] for x in range(2) for y in range(2)]
>>> result
[[0, 0], [0, 1], [1, 0], [1, 1]]
>>>

Set:无序、不可重复

初始化

1.创建一个空的set

1
distances = set()

2.为set提供一个数据列表(需要用大括号包围

1
2
3
>>> distances = {10.6,11,8,10.6,"two",7}
>>> distances
{8, 10.6, 11, 'two', 7} # 自动过滤掉了重复的数据

3.为set指定一个现有的列表

1
2
3
4
>>> list = [2,2,3,5,6]
>>> distances = set(list)
>>> distances
{2, 3, 5, 6}

零碎知识点

list列表分片

列表分片主要用于获取列表的一个子部分,即通过L[x:y]取得并返回列表L在偏移量x到y(包括x不包括y)之间的一个新列表,如下所示:

1
2
>>> [1,2,3,4,5,6][2:5]
[3, 4, 5]

另外,如果偏移量留空,则第一个偏移量默认为列表的头部,第二个默认为末尾:

1
2
>>> [1,2,3,4,5,6][:]
[1, 2, 3, 4, 5, 6]

如果这样做,相当于对原列表做一个浅拷贝。

分片实际还接收第三个参数,其代表步长,默认情况下,该值为1。下面将步长改为2:

1
2
>>> [1,2,3,4,5,6][::2]
[1, 3, 5]

如果把步长设为负值会有什么效果呢?

1
2
>>> [1,2,3,4,5,6][::-2]
[6, 4, 2]

相当于反转了列表,从列表的尾部开始遍历。

工厂函数

工厂函数用于创建某种类型的新的数据项,例如set()就是一个工厂函数,因为它会创建一个新的集合。

hoxis wechat
一个脱离了高级趣味的程序员,关注回复1024有惊喜~
赞赏一杯咖啡
0%